2.Dart 语言的进阶
注释
注释分为单行注释,多行注释,文档注释,除文档注释之外,其他的注释在编译时会自动舍弃。
单行注释://
多行注释:/* */
文档注释:/// 或者 /** */
类
import 'dart:math';
class Point{
  num x,y; //实例变量
  num distanceFromOrigin;
  // 非命名的构造函数
  Point(this.x,this.y):distanceFromOrigin = sqrt(x*x+y*y);
  // 命名的构造函数
  Point.origin():this(0,0);
  Point.fromJson(Map<String,num>json):this(json['x'],json['y']);
  Point.withAssert(this.x,this.y)
    :assert(x>=0),
  distanceFromOrigin = sqrt(x*x+y*y);
  // 计算与另外一个点的距离
  num distnceTo(Point other){
    var dx = x-other.x;
    var dy = y - other.y;
    return sqrt(dx *dx +dy*dy);
  }
  @override // 覆盖 Obj ,即作为所有类的基类上的方法
  String toString()=> 'Point($x,$y)';
  class ImmutablePoint {
    static final origin = const ImmutablePoint(0,0);
    final num x,y;
    const ImmutablePoint(this.x,this.y);
  }
}
class Person { // 创建一个 Person 父类
  String firstName;
  Person.formJson(Map data){
    print('in Person');
  }
}
class Employee extends Person{// 创建一个Employee 继承 Person 类
  Employee.fromJson(Map data):super.fromJson(data){ // 该构造函数会调用父类的构造函数
    print('in Employee');
  }
}
// 一个日志类,错误时打印日志
class Logger {
  final String name;
  bool mute = false; // 表示是否开启
  static final _cache = <String,Logger>{};
  factory Logger(String name){ // 工厂方法,我也不知道是啥意思 
    if(_cache.containsKey(name)){
      return _cache[name];
    }else{
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }
  Logger._internal(this.name); // 添加 _ 表示的是,私有的构造方法
  void log(String msg){ // 在没有定义的情况下会打印日志
    if(!mute) print(msg);
  }
}
// 一个矩形的类
class Rectangle{
  num left,top,width,height;
  Rectangle(this.left,this.top,this.width,this.height);
  num get right => left +width; 
  set right(num value) =>left = value-width; // 更改 right 的值时,left 赋值为 value - width
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}
// 抽象类,需要有具体的进行实现这个抽象的类
abstract class Doer{
  void doSomething();
}
class EffectiveDoer extends Doer {
  void doSomething(){
    print("all right,that's good");
  }
}
// 类的实现
class Person1{
  final _name;
  Person1(this._name);
  String greet(String who) => 'hello $who. I am $_name.';
} // 实现所有的接口,包括实例变量
class Impostor implements Person1 {
  get _name =>'';
  String greet(String who) => 'hi $who. I know who you are.';
}
String greetBob(Person1 person)=> person.greet('Bob');
class Television {
  void turnOn(){
    print('illuminate display');
    print('activateIr sensor');
  }
}
class SmartTelevision extends Television{
  @override // 覆盖父类的方法
  void turnOn(){
    super.turnOn();// 调用了父类的方法
    print("智能电视");
    print('支持多国语言');
    print('体验需进行收费');
  }
}
// 定义了一个向量
class Vector {
  final int x,y;
  Vector(this.x,this.y);
  // x 向量加上 x 向量,y 向量,加上 y 向量
  Vector operator +(Vector v)=> Vector(x+v.x,y+v.y);
  Vector operator -(Vector v) => Vector(x-v.x,y-v.y);
  @override // 和下面的 override 一样,用于覆盖基类,基类的操作方法
  int get hashCode{
    int result = 17;
    result = 37*result +x.hashCode;
    result = 37*result + y.hashCode;
    return result;
  }
  @override
  bool operator ==(dynamic other){
    if(other is! Vector) return false;
    Vector vector = other;
    return (vector.x == x && vector.y == y)
  }
}
class A{
  @override
  void noSuchMethod(Invocation invocation){
    print('you tried to use a non-existent menber:'+'${invocation.memberName}');
  }
}
// 类的使用
void main(){
  var p  = Point(2,2);
  p.y = 3;
  assert(p.y == 3);
  p?.y = 4; // 只有不为空的时候才执行对于成员的访问,避免 null 执行方法的错误
  var p1 = Point(2,2);
  var p2 = Point.formJson({'x':1,'y':2});
  print(p2);
  
  var ip = const ImmutablePoint(2,2);
  
  var a = const ImmutablePoint(1,1);
  var b = const ImmutablePoint(1,1);
  assert(identical(a,b));
  
  const pointAndLine ={
    'point':[ImmutablePoint(0,0)],
    'line':[ImmutablePoint(1,10),ImmutablePoint(-2,11)],
  };
  a = const ImmutablePoint(1,1); 
  b = ImmutablePoint(1,1);// b 不使用 const进行创建,所以,a != b
  assert(!identical(a,b));
  print('Type of a is ${a.runtimeType}');
  
  var emp = Employee.from Json({});
  if (emp is Person){
    emp.firstName='Bob';
  }
  (emp as Person).firstName = 'Bob';
  
  var logger = Logger('UI');
  logger.log('Button clicked');
  var rect = Rectangle(3,4,20,15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
  print(greetBob(Person1('Kathy')));
  print(greetBob(Impostor()));
  
  final v = Vector(2,3);
  final w = Vector(2,2);
  assert(v+w== Vector(4,5));
  assert(v-w == Vector(0,1));
  
  dynamic a1 = A(); // 必须设置为 dynamic 否则在编译的时候就会报错
  a1.c();// 在 a1 上,调用不存在的 c 方法,会报一个错误
}